﻿using System;
using System.Drawing;
using System.IO;
using Devonline.Core;

namespace Devonline.Utils
{
    public static class ImageUtility
    {
        /// <summary>
        /// 制作缩略图, 不校验图片文件类型
        /// </summary>
        /// <param name="fileName">文件名</param>
        public static void CreateDefaultThumbnail(string fileName)
        {
            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException("原文件不存在!", fileName);
            }

            using var fileStream = File.OpenRead(fileName);
            using var image = Image.FromStream(fileStream);
            CreateThumbnail(image, AppSettings.DEFAULT_IMAGE_THUMBNAIL_SIZE, AppSettings.DEFAULT_IMAGE_THUMBNAIL_SIZE, AppSettings.DEFAULT_IMAGE_THUMBNAIL_PREFIX + Path.GetFileName(fileName));
        }
        /// <summary>
        /// 制作图片文件缩略图, 不校验图片文件类型
        /// </summary>
        /// <param name="fileName">图片对象</param>
        /// <param name="newFileName">新图路径</param>
        /// <param name="maxWidth">最大宽度</param>
        /// <param name="maxHeight">最大高度</param>
        public static void CreateThumbnail(string fileName, int maxWidth, int maxHeight, string newFileName)
        {
            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException("文件不存在!", fileName);
            }

            using var fileStream = File.OpenRead(fileName);
            using var image = Image.FromStream(fileStream);
            CreateThumbnail(image, maxWidth, maxHeight, newFileName);
        }
        /// <summary>
        /// 制作缩略图
        /// </summary>
        /// <param name="original">图片对象</param>
        /// <param name="newFileName">新图路径</param>
        /// <param name="maxWidth">最大宽度</param>
        /// <param name="maxHeight">最大高度</param>
        public static void CreateThumbnail(Image original, int maxWidth, int maxHeight, string newFileName)
        {
            if (original == null)
            {
                throw new ArgumentNullException(nameof(original));
            }

            var newSize = ResizeImage(original.Width, original.Height, maxWidth, maxHeight);
            using var image = new Bitmap(original, newSize);

            try
            {
                image.Save(newFileName, original.RawFormat);
            }
            finally
            {
                original.Dispose();
            }
        }

        /// <summary>
        /// 计算新尺寸
        /// </summary>
        /// <param name="width">原始宽度</param>
        /// <param name="height">原始高度</param>
        /// <param name="maxWidth">最大新宽度</param>
        /// <param name="maxHeight">最大新高度</param>
        /// <returns></returns>
        private static Size ResizeImage(int width, int height, int maxWidth, int maxHeight)
        {
            if (maxWidth <= 0)
            {
                maxWidth = width;
            }

            if (maxHeight <= 0)
            {
                maxHeight = height;
            }

            float MAX_WIDTH = maxWidth;
            float MAX_HEIGHT = maxHeight;
            var ASPECT_RATIO = MAX_WIDTH / MAX_HEIGHT;

            int newWidth, newHeight;
            float originalWidth = width;
            float originalHeight = height;

            if (originalWidth > MAX_WIDTH || originalHeight > MAX_HEIGHT)
            {
                float factor;
                if (originalWidth / originalHeight > ASPECT_RATIO)
                {
                    factor = originalWidth / MAX_WIDTH;
                    newWidth = Convert.ToInt32(originalWidth / factor);
                    newHeight = Convert.ToInt32(originalHeight / factor);
                }
                else
                {
                    factor = originalHeight / MAX_HEIGHT;
                    newWidth = Convert.ToInt32(originalWidth / factor);
                    newHeight = Convert.ToInt32(originalHeight / factor);
                }
            }
            else
            {
                newWidth = width;
                newHeight = height;
            }

            return new Size(newWidth, newHeight);
        }
    }
}
